package com.jwsoft.manager.core.gateway.controller;

import com.bifang.assistant.common.vo.BasePageVO;
import com.bifang.assistant.common.vo.BaseVO;
import com.bifang.engine.assistant.core.domain.AppResponse;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.cache.redis.RedisHelper;
import com.bifang.engine.protect.core.annotation.Idempotent;
import com.bifang.engine.protect.core.annotation.NoSignCrypto;
import com.bifang.module.base.common.vo.tree.TreeVO;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.constant.EduCache;
import com.jwsoft.manager.common.vo.address.AddressSchoolVO;
import com.jwsoft.manager.common.vo.address.AddressTreeSchoolVO;
import com.jwsoft.manager.common.vo.eduAddressTree.*;
import com.jwsoft.manager.common.vo.eduAddressTreeInitial.EduAddressTreeInitialQueryVO;
import com.jwsoft.manager.common.vo.eduAddressTreeSchool.EduAddressSchoolRelationAddVO;
import com.jwsoft.manager.common.vo.eduAddressTreeSchool.EduAddressTreeSchoolQueryVO;
import com.jwsoft.manager.common.vo.eduAddressTreeSchool.EduAddressTreeSchoolRemoveVO;
import com.jwsoft.manager.common.vo.eduAddressTreeSchool.EduAddressTreeSchoolVO;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.common.vo.eduStudentEnrollKindergarten.EduStudentEnrollKindergartenQueryVO;
import com.jwsoft.manager.core.integration.eduAddressTree.EduAddressTreeIntegration;
import com.jwsoft.manager.core.integration.eduAddressTree.impl.AddressInfoAndSchool;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 前端控制器
 *
 * @author fangs
 * @since 2023-01-12
 */
@RestController
@RequestMapping(value = "/doc/api")
@Tag(name = "地址树相关接口", description = "地址树相关接口")
public class EduAddressTreeController {
    @Autowired
    EduAddressTreeIntegration eduAddressTreeIntegration;

    @Autowired
    private RedisHelper redisHelper;

    @Operation(summary = "地址树转存ES", description = "地址树转存ES")
    @PostMapping(value = "/eduAddressTree0001", produces = "application/json;charset=UTF-8")
    public AppResponse parseAddressAuto(@RequestBody BaseVO vo) {
        eduAddressTreeIntegration.initAddressTreeEs(vo);
        return AppResponse.success();
    }

    @Operation(summary = "地址解析", description = "地址解析")
    @PostMapping(value = "/eduAddressTree0002", produces = "application/json;charset=UTF-8")
    public AppResponse<AddressVO> parseAddressAuto(@RequestBody AddressReqVO reqVO) {
        return AppResponse.successData(eduAddressTreeIntegration.parseAddressAuto(reqVO));
    }

    @Operation(summary = "分页获取下级节点", description = "分页获取下级节点")
    @PostMapping(value = "/eduAddressTree0004", produces = "application/json;charset=UTF-8")
    public AppResponse<PageInfo<AddressTreeVO>> parseAddressAuto(@RequestBody @Valid AddressTreeReqVO addressTreeReqVO) {
        return AppResponse.successData(eduAddressTreeIntegration.getListByParentId(addressTreeReqVO));
    }

    @Operation(summary = "获取地址树节点绑定的学校列表", description = "获取地址树节点绑定的学校列表")
    @PostMapping(value = "/eduAddressTree0005", produces = "application/json;charset=UTF-8")
    public AppResponse<PageInfo<EduAddressTreeSchoolVO>> parseAddressAuto(@RequestBody EduAddressTreeSchoolQueryVO treeSchoolQueryVO) {
        return AppResponse.successData(eduAddressTreeIntegration.getSchool(treeSchoolQueryVO));
    }

    @Operation(summary = "地址树节点移动", description = "获取地址树节点绑定的学校列表")
    @PostMapping(value = "/eduAddressTree0006", produces = "application/json;charset=UTF-8")
    public AppResponse moveTreeNode(@RequestBody MoveNodeReqVO moveNodeReqVO) {
        eduAddressTreeIntegration.moveTreeNode(moveNodeReqVO);
        return AppResponse.success();
    }
    @Operation(summary = "根据用户信息获取乡镇街道", description = "根据用户信息获取乡镇街道")
    @PostMapping(value = "/eduAddressTree0007", produces = "application/json;charset=UTF-8")
    public AppResponse<List<TreeVO>> getTownTreeByUser(@RequestBody BaseVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.getTownTreeByUser(vo));
    }
    @Operation(summary = "根据主键获取地址详细信息", description = "根据主键获取地址详细信息")
    @PostMapping(value = "/eduAddressTree0008", produces = "application/json;charset=UTF-8")
    public AppResponse<EduAddressTreeInfoVO> queryAddressInfoById(@RequestBody @Valid AddressTreeQueryVO vo){
        return AppResponse.successData(eduAddressTreeIntegration.queryAddressInfoById(vo));
    }


    @Operation(summary = "删除地址关联学校信息", description = "删除地址关联学校信息")
    @PostMapping(value = "/eduAddressTree0009", produces = "application/json;charset=UTF-8")
    public AppResponse removeSchoolRelation(@RequestBody EduAddressTreeSchoolRemoveVO vo){
        eduAddressTreeIntegration.removeSchoolRelation(vo);
        return AppResponse.success();
    }

    @Operation(summary = "查询地址能关联的学校信息", description = "查询地址能关联的学校信息")
    @PostMapping(value = "/eduAddressTree0010", produces = "application/json;charset=UTF-8")
    public AppResponse<PageInfo<EduSchoolVO>> querySchoolRelation(@RequestBody EduAddressTreeSchoolQueryVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.querySchoolRelation(vo));
    }


    @Operation(summary = "添加学校关联信息", description = "添加学校关联信息")
    @PostMapping(value = "/eduAddressTree0011", produces = "application/json;charset=UTF-8")
    public AppResponse addSchoolRelation(@RequestBody @Valid EduAddressSchoolRelationAddVO vo) {
        eduAddressTreeIntegration.addSchoolRelation(vo);
        return AppResponse.success();
    }

    @Operation(summary = "保存地址树节点详细信息", description = "保存地址树节点详细信息")
    @PostMapping(value = "/eduAddressTree0012", produces = "application/json;charset=UTF-8")
    public AppResponse saveAddressTreeInfo(@RequestBody EduAddressTreeInfoVO vo){
        eduAddressTreeIntegration.saveAddressTreeInfo(vo);
        return AppResponse.success();
    }

    @Operation(summary = "地址树节点新增", description = "地址树节点新增")
    @PostMapping(value = "/eduAddressTree0013", produces = "application/json;charset=UTF-8")
    public AppResponse<EduAddressTreeVO> addAddressTreeNode(@RequestBody EduAddressTreeInfoVO vo) {
        EduAddressTreeVO eduAddressTreeVO = eduAddressTreeIntegration.addAddressTreeNode(vo);
        return AppResponse.successData(eduAddressTreeVO);
    }

    @Operation(summary = "根据主键删除地址树节点", description = "根据主键删除地址树节点")
    @PostMapping(value = "/eduAddressTree0014", produces = "application/json;charset=UTF-8")
    public AppResponse deleteByAddressId(@RequestBody EduAddressTreeKeyVO vo) {
        eduAddressTreeIntegration.deleteByAddressId(vo);
        return AppResponse.success();
    }

    @Operation(summary = "从多个节点名字中抽取共同字段为新的父节点", description = "从多个节点名字中抽取共同字段为新的父节点")
    @PostMapping(value = "/eduAddressTree0015", produces = "application/json;charset=UTF-8")
    public AppResponse mergeNodeAndCreParent(@RequestBody AddressTreeMergeVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.mergeNodeAndCreParent(vo));
    }

    @Operation(summary = "根据主键修改叶子节点", description = "根据主键修改叶子节点")
    @PostMapping(value = "/eduAddressTree0016", produces = "application/json;charset=UTF-8")
    public AppResponse editLeafNodeByAddressId(@RequestBody EduAddressTreeKeyVO vo) {
        eduAddressTreeIntegration.editLeafNodeByAddressId(vo);
        return AppResponse.success();
    }

    @Operation(summary = "节点合并", description = "节点合并")
    @PostMapping(value = "/eduAddressTree0017", produces = "application/json;charset=UTF-8")
    public AppResponse mergeNode(@RequestBody AddressTreeMergeVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.mergeNode(vo));
    }

    @Operation(summary = "地址识别并匹配学区", description = "地址识别并匹配学区")
    @PostMapping(value = "/eduAddressTree0018", produces = "application/json;charset=UTF-8")
    public AppResponse<AddressInfoAndSchool> editLeafNodeByAddressId(@RequestBody AddressReqVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.addressParseAndMatchSchool(vo));
    }

    @Operation(summary = "节点合并应用接口", description = "节点合并应用接口")
    @PostMapping(value = "/eduAddressTree0019", produces = "application/json;charset=UTF-8")
    public AppResponse<Map<Long, Long>> applyMarge(@RequestBody AddressTreeApplyVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.applyMarge(vo));
    }

    @Operation(summary = "分页获取学校账号的树节点信息", description = "分页获取学校账号的树节点信息")
    @PostMapping(value = "/eduAddressTree0020", produces = "application/json;charset=UTF-8")
    public AppResponse<PageInfo<AddressTreeForSchoolVO>> getSchoolAddressTree(@RequestBody @Valid AddressTreeSchoolVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.getSchoolAddressTree(vo));
    }

    @Operation(summary = "学校用户关联树节点接口", description = "学校用户关联树节点接口")
    @PostMapping(value = "/eduAddressTree0021", produces = "application/json;charset=UTF-8")
    public AppResponse schoolRelationAddress(@RequestBody AddressSchoolVO vo) {
        eduAddressTreeIntegration.schoolRelationAddress(vo);
        return AppResponse.success();
    }

    @Operation(summary = "开启或关闭某节点用于地址匹配", description = "开启或关闭某节点用于地址匹配")
    @PostMapping(value = "/eduAddressTree0022", produces = "application/json;charset=UTF-8")
    public AppResponse schoolRelationAddress(@RequestBody AddressTreeSyncVO vo) {
        eduAddressTreeIntegration.syncAddressTreeEs(vo);
        return AppResponse.success();
    }


    @Operation(summary = "重新统计叶子节点数", description = "重新统计叶子节点数")
    @PostMapping(value = "/eduAddressTree0023", produces = "application/json;charset=UTF-8")
    public AppResponse evaluateLeafNum(@RequestBody EduAddressTreeVO vo) {
        if (vo == null || vo.getAddressId() == null) {
            throw new AppException("参数错误");
        }
        if (eduAddressTreeIntegration.isFinishEvaluateLeafNum(vo)) {
            eduAddressTreeIntegration.startEvaluateLeafNum(vo);
        } else {
            throw new AppException("叶子节点数正在统计中，请稍后再试");
        }
        return AppResponse.success();
    }

    @Operation(summary = "检查叶子节点数量是否统计完成", description = "检查叶子节点数量是否统计完成")
    @PostMapping(value = "/eduAddressTree0024", produces = "application/json;charset=UTF-8")
    public AppResponse<Boolean> isFinishEvaluateLeafNum(@RequestBody BaseVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.isFinishEvaluateLeafNum(vo));
    }

    @Operation(summary = "根据节点id删除，被删除节点的子节点也会被删除", description = "根据节点id删除，被删除节点的子节点也会被删除")
    @PostMapping(value = "/eduAddressTree0025", produces = "application/json;charset=UTF-8")
    public AppResponse isFinishEvaluateLeafNum(@RequestBody AddressTreeBatchKeyVO vo) {
        eduAddressTreeIntegration.removeBatchById(vo);
        return AppResponse.success();
    }

    @Operation(summary = "学校绑定预警信息", description = "学校绑定预警信息")
    @PostMapping(value = "/eduAddressTree0026", produces = "application/json;charset=UTF-8")
    public AppResponse<PageInfo<AddressBoundCheckVO>> queryBoundLessAsLeafNodes(@RequestBody BasePageVO vo) {
        PageInfo<AddressBoundCheckVO> res = eduAddressTreeIntegration.queryBoundLessAsLeafNodes(vo);
        return AppResponse.successData(res);
    }

    @Idempotent(expire="PT10S") //2秒内防重复提交
    @Operation(summary = "学校绑定预警信息exec导出",description = "学校绑定预警信息exec导出")
    @PostMapping(value = "/eduAddressTree0027", produces = "application/json;charset=UTF-8")
    @NoSignCrypto
    public void downloadBoundWarningInfo(@RequestBody @Validated AddressBoundCheckVO vo, HttpServletResponse response) {
        eduAddressTreeIntegration.downloadBoundWarningInfo(vo,response);
    }

    @Operation(summary = "地址识别并匹配学区(查询)", description = "地址识别并匹配学区(查询)")
    @PostMapping(value = "/eduAddressTree0028", produces = "application/json;charset=UTF-8")
    @NoSignCrypto
    public AppResponse<AddressInfoAndSchool> addressParseAndMatchSchool(@RequestBody AddressReqVO vo) {
        return AppResponse.successData(eduAddressTreeIntegration.addressParseAndMatchSchool(vo));
    }

    @Operation(summary = "新地址识别并匹配学区(保存)", description = "地址识别并匹配学区(保存)")
    @PostMapping(value = "/eduAddressTree0029", produces = "application/json;charset=UTF-8")
    @NoSignCrypto
    public AppResponse<AddressInfoAndSchool> addressMatchSchoolAndSave(@RequestBody AddressReqVO vo) {
        eduAddressTreeIntegration.addressMatchSchoolAndSave(vo);
        return AppResponse.successMsg("解析成功");
    }

    @Idempotent(expire="PT2S") //2秒内防重复提交
    @Operation(summary = "已处理的地址重新解析",description = "已处理的地址重新解析")
    @PostMapping(value = "/eduAddressTree0030", produces = "application/json;charset=UTF-8")
    @NoSignCrypto
    public AppResponse addressAfreshParse(@RequestBody @Validated EduAddressTreeInitialQueryVO vo) {
        eduAddressTreeIntegration.addressAfreshParse(vo);
        return AppResponse.successMsg("重新解析成功！");
    }

    @Idempotent(expire="PT2S") //2秒内防重复提交
    @Operation(summary = "地址解析定时任务清除缓存",description = "地址解析清除缓存")
    @PostMapping(value = "/eduAddressTree0031", produces = "application/json;charset=UTF-8")
    public AppResponse clearAddressFormatJobHandler(@RequestBody @Validated BaseVO vo) {
        String redisKey= EduCache.EDU_DATA_TASK_DETAIL+"addressFormatJobHandler";
        redisHelper.del(redisKey);
        return AppResponse.successMsg("操作成功！");
    }


}
